#include "yb_log_browse.h"
#include "ui_yb_log_browse.h"

#include "pub_var.h"
#include <QSettings>
#include <QMessageBox>
#include <QJsonDocument>
#include <QNetworkReply>
#include <QDir>

//#include "json.hpp"
//using json = nlohmann::json;

Yb_log_browse::Yb_log_browse(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Yb_log_browse)
{
    ui->setupUi(this);

    qDebug()<<"\nYb_log_browse 初始化\n";

    //恢复当前窗口位置
    QSettings setIni("clin.ini", QSettings::IniFormat);
    QRect rct = setIni.value("windowState/log_browse").toRect();
    this->setGeometry(rct);

    //数据库连接
    qrm = new QSqlQuery(pub::db_m);
    qro = new QSqlQuery(pub::db_o);
    qrot = new QSqlQuery(pub::db_o);
    md_list = new QSqlQueryModel();

    //网络参数
    request.setUrl(QUrl(pub::hos_ybjy));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    ui->de_date0->setDate(QDate::currentDate());
    ui->de_date1->setDate(QDate::currentDate());

    dlgDelay = new Pub_pop_delay();

    //文件存储路径
    downloadPath = setIni.value("system/downloadPath").toString();

    if(downloadPath.isEmpty()){
        //下载路径未设置，设置为默认值
        downloadPath = "/0down";
        setIni.setValue("system/downloadPath", "/0down");

    }

    QDir d(downloadPath);

    downloadPath = d.path(); //过滤配置文件可能出现的错误字符

    if( ! d.exists() ){
        //路径不存在，按指定的名字建立新路径

        if(!d.mkdir(downloadPath)){
            QMessageBox::warning(this, "注意", "指定文件存储路径无效！默认路径为本级盘符:\\0down\\");
            downloadPath = "/0down";
            setIni.setValue("system/downloadPath", downloadPath);
            d.setPath(downloadPath);
            if(!d.exists() && !d.mkdir(downloadPath)){
                QMessageBox::warning(this, "注意", "建立默认路径失败!");
            }
        }
    }

    cur_busi_code = "";
    cur_atinc = "";

    ui->trw_in->setColumnCount(2);
    ui->trw_in->setHeaderLabels({"Key", "Value"});

    ui->trw_out->setColumnCount(2);
    ui->trw_out->setHeaderLabels({"Key", "Value"});

    ui->trw_in->setItemDelegate(new ElideDelegate(ui->trw_in));
    ui->trw_out->setItemDelegate(new ElideDelegate(ui->trw_out));

    ui->trw_in->setHidden(false);
    ui->trw_out->setHidden(false);
    ui->pt_para_in->setHidden(true);
    ui->pt_para_out->setHidden(true);

    qDebug()<<"\nYb_log_browse 初始化结束\n";

}

Yb_log_browse::~Yb_log_browse()
{
    delete ui;
}

void Yb_log_browse::closeEvent(QCloseEvent *event)
{
    qDebug()<<"\ncloseEvent 开始\n";
    Q_UNUSED(event);
    QSettings setIni("clin.ini", QSettings::IniFormat);
    setIni.setValue("windowState/log_browse", QVariant(this->geometry()));

    emit destroyW( "yb_log_browse" );

    qDebug()<<"\ncloseEvent 结束\n";
}

void Yb_log_browse::on_pb_exit_clicked()
{
    close();
}

void Yb_log_browse::on_pb_require_clicked()
{
    qDebug()<<"\non_pb_require 开始\n";

    QString cond_busi_code = "";
    QString cond_date = "";
    QString cond_clinic_code = "";
    QString cond_user_code = "";

    QString cond_card_no = ui->le_card_no->text().trimmed();

    QString dt0 = ui->de_date0->date().toString("yyyy-MM-dd") + " 00:00:00";
    QString dt1 = ui->de_date1->date().toString("yyyy-MM-dd") + " 23:59:59";

    //指定交易时间
    if(ui->ckb_busi_time->isChecked())
    {
        cond_date = " and tmstmp between str_to_date('%1','%Y-%m-%d %H:%i:%s') "
                    " and str_to_date('%2','%Y-%m-%d %H:%i:%s')";
        cond_date = cond_date.arg(dt0).arg(dt1);
    }

    //指定病志号，根据病志号提取 clinic code
    if(ui->rb_card_no->isChecked() && !cond_card_no.isEmpty())
    {

        if(ui->ckb_busi_time->isChecked())
        {
            //指定交易时间
            qDebug()<<"使用病志号和日期查询 clinic_code";
            sq = "select clinic_code from fin_opr_register "
                 " where card_no = LPAD('%1', 10, '0') "
                 " and reg_date between to_date('%2', 'yyyy-mm-dd hh24:mi:ss')"
                 " and to_date('%3', 'yyyy-mm-dd hh24:mi:ss')";
            sq = sq.arg(cond_card_no)
                    .arg(dt0)
                    .arg(dt1);
            qDebug()<<sq<<"\n";

            qro->exec(sq);

            if(qro->next())
            {
                cond_clinic_code = " and clinic_code = '"
                        + qro->value(0).toString() + "' ";

                //ui->le_clinic_code->setText(qro->value(0).toString());
            }
            else
            {
                QMessageBox::information(this, "注意", "指定就诊日期找不到病志号 "
                                                     + cond_card_no + " ！");
                return;
            }

        }
        else
        {
            //未指定交易时间
            qDebug()<<"使用病志号查询 clinic_code";
            sq = "select distinct clinic_code from fin_opr_register "
                 " where card_no = LPAD('%1', 10, '0') ";
            sq = sq.arg(cond_card_no);
            qDebug()<<sq<<"\n";

            qro->exec(sq);
            QString code_list = "'code'";
            while(qro->next())
            {
                code_list += ",'" + qro->value(0).toString() + "'";
            }

            if(code_list == "'code'")
            {
                QMessageBox::information(this, "注意", "未找到指定的病志号 "
                                                     + cond_card_no + " ！");
                return;
            }

            cond_clinic_code = " and clinic_code in (" + code_list + ") ";

        }
    }
    else if(ui->rb_clinic_code->isChecked()
            && !ui->le_clinic_code->text().trimmed().isEmpty())
    {
        //clinic code 非空
            cond_clinic_code = " and clinic_code = '"
                    + ui->le_clinic_code->text().trimmed() + "' ";
    }

    //指定交易代码
    if(!ui->le_busi_code->text().trimmed().isEmpty())
    {
        cond_busi_code = " and ywbh = '"
                + ui->le_busi_code->text().trimmed() + "'";
    }

    //指定用户代码
    if(!ui->le_user_code->text().trimmed().isEmpty())
    {
        cond_user_code = " and user = '"
                         + ui->le_user_code->text().trimmed() + "'";
    }

    qDebug()<<"查询符合条件的医保交易记录";
    sq = " select atinc, ywbh 业务编码, user 用户代码, clinic_code, jysj 入参时间,"
         " date_format(tmstmp,'%Y-%m-%d %H:%i:%s') 出参时间, v_in, v_out "
         " from com_business"
         " where 1 = 1 ";

    QString sub_sq = "";

    if(!cond_clinic_code.isEmpty())
    {
        //clinic_code 非空，优先使用 clinic_code 字段索引
        sub_sq += cond_clinic_code + cond_busi_code +cond_date;
    }
    else if(!cond_busi_code.isEmpty())
    {
        //clinic_code 空 且 交易代码非空，使用 ywbh + jysj 字段索引
        sub_sq += cond_busi_code + cond_date + cond_clinic_code;
    }
    else if(ui->ckb_busi_time->isChecked())
    {
        //指定日期
        sub_sq = cond_date ;
    }

    sub_sq += cond_user_code ;

    if(sub_sq.isEmpty())
    {
        QMessageBox::information(this, "注意", "未指定有效的查询条件！");
        return;
    }

    if(ui->ckb_abnormal->isChecked())
    {
        sub_sq += " and infcode <> 0 ";
    }

    sq += sub_sq + " order by jysj limit 9999 ";

    qDebug()<<sq<<"\n";

    dlgDelay->setText("正在提取数据。。。");
    dlgDelay->setModal(true);
    dlgDelay->setNeedClose(false);
    dlgDelay->show();
    qApp->processEvents();

    md_list->setQuery(sq, pub::db_m);

    ui->tv_list->setModel(md_list);

    int w = ui->tv_list->width();

    pub::setColumnWidth(ui->tv_list, "0.1^0.1^0.1^0.12^0.28^0.2^0^0^", w);


    dlgDelay->setNeedClose(true);
    dlgDelay->closeWindow();

    if(md_list->rowCount() < 1)
    {
        QMessageBox::information(this, "注意", "指定的查询条件找不到数据！");
    }

    qDebug()<<"\non_pb_require 结束\n";
}

void Yb_log_browse::on_pb_export_clicked()
{
    qDebug()<<"\non_pb_export_clicked 开始\n";

    if(cur_busi_code.isEmpty())
    {
        QMessageBox::information(this, "注意", "未选定有效记录！");
        return;
    }

    QString path = downloadPath + "/log_" ;
    path += cur_busi_code + "_" + cur_atinc + ".txt";

    qDebug()<<"目标文件："<<path<<"\n";

    QFile f;

    if(f.exists(path))
    {
        qDebug()<<"目标文件已经存在，移除。"<<"\n";
        f.remove(path);
    }

    f.setFileName(path);


    //打开文件,只写方式
    bool isOK = f.open(QIODevice::WriteOnly);
    if (!isOK){
        QMessageBox::information(this,"注意","创建输出文件失败！");
        return;
    }

    QString str = "交易代码：" + cur_busi_code ;
    f.write(str.toLocal8Bit());

    str = "\r\n\r\n入参:\r\n\r\n";
    str += cur_in;
    f.write(str.toLocal8Bit());

    str = "\r\n\r\n出参:\r\n\r\n";
    str += cur_out;
    f.write(str.toLocal8Bit());

    f.close();

    QMessageBox::information(this,"注意", path+" 文件已生成！");

    qDebug()<<"\non_pb_export_clicked 结束\n";
}

void Yb_log_browse::on_tv_list_clicked(const QModelIndex &index)
{

    cur_busi_code = index.siblingAtColumn(1).data().toString();
    cur_atinc = index.siblingAtColumn(0).data().toString();
    cur_in = index.siblingAtColumn(6).data().toString();
    cur_out = index.siblingAtColumn(7).data().toString();

    //查询业务编码含义
    sq = "select * from com_busi_desc where code = '"
         + cur_busi_code + "'";
    qrm->exec(sq);
    qrm->next();

    QString describe = qrm->value("type1").toString();
    describe += " - " + qrm->value("type2").toString();
    describe += " - " + qrm->value("name").toString();

    ui->le_busi_describe->setText(describe);

    //入参    
    QJsonDocument jsonDoc = QJsonDocument::fromJson(cur_in.toUtf8());

    ui->trw_in->clear();

    if (jsonDoc.isNull())
    {
        qDebug() << "Failed to parse JSON!";
        ui->trw_in->setHidden(true);
        ui->pt_para_in->setHidden(false);
        ui->pt_para_in->setPlainText(cur_in);
    }
    else
    {
        ui->trw_in->setHidden(false);
        ui->pt_para_in->setHidden(true);

        QJsonObject root_in = jsonDoc.object();
        QTreeWidgetItem *rootItem_in = new QTreeWidgetItem(ui->trw_in);
        rootItem_in->setText(0, "Root");
        populateTree(rootItem_in, root_in);

        ui->trw_in->expandAll(); // 展开所有节点
        int w = ui->trw_in->width();
        ui->trw_in->setColumnWidth(0, w * 0.4);
        ui->trw_in->setColumnWidth(1, w * 0.5);

    }

    //出参
    jsonDoc = QJsonDocument::fromJson(cur_out.toUtf8());

    ui->trw_out->clear();

    if (jsonDoc.isNull())
    {
        ui->trw_out->setHidden(true);
        ui->pt_para_out->setHidden(false);
        ui->pt_para_out->setPlainText(cur_out);
    }
    else
    {
        ui->trw_out->setHidden(false);
        ui->pt_para_out->setHidden(true);

        QJsonObject root_out = jsonDoc.object();
        QTreeWidgetItem *rootItem_out = new QTreeWidgetItem(ui->trw_out);
        rootItem_out->setText(0, "Root");
        populateTree(rootItem_out, root_out);

        ui->trw_out->expandAll(); // 展开所有节点

        int w = ui->trw_out->width();
        ui->trw_out->setColumnWidth(0, w * 0.4);
        ui->trw_out->setColumnWidth(1, w * 0.5);

    }

}

void Yb_log_browse::on_tv_list_doubleClicked(const QModelIndex &index)
{
    on_tv_list_clicked(index);
}

void Yb_log_browse::populateTree(QTreeWidgetItem *parent,
                                 const QJsonValue &value)
{
    if (value.isObject())
    {
        QJsonObject obj = value.toObject();
        for (const QString &key : obj.keys())
        {
            QTreeWidgetItem *item = new QTreeWidgetItem(parent);
            item->setText(0, key);
            populateTree(item, obj[key]);
        }
    }
    else if (value.isArray())
    {
        QJsonArray arr = value.toArray();
        for (int i = 0; i < arr.size(); ++i)
        {
            QTreeWidgetItem *item = new QTreeWidgetItem(parent);
            item->setText(0, QString("[%1]").arg(i));
            populateTree(item, arr[i]);
        }
    }
    else
    {
        // 直接填充到父节点的第二列，不创建子节点
        if (value.isString())
        {
            parent->setText(1, value.toString());
        }
        else if (value.isDouble())
        {
            parent->setText(1, QString::number(value.toDouble()));
        }
        else if (value.isBool())
        {
            parent->setText(1, value.toBool() ? "true" : "false");
        }
        else if (value.isNull())
        {
            parent->setText(1, "null");
        }
    }
}

